import pandas as pd
from PIL import Image
from docx import Document
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.opc.oxml import parse_xml
from docx.oxml.ns import nsdecls
from docx.shared import RGBColor, Pt
from datareport.api.annotation.Font import Font
from datareport.impl.paragraph.base.BaseParagraph import BaseParagraph


class BodyWriter:

    def __init__(self, doc: Document):
        self.height=0
        self.doc: Document = doc

    def writer(self, para: BaseParagraph):
        print('{}开始'.format(para))
        """
        写入数据
        :param para: 段落
        :return:
        """

        # 总的段落格式
        paragraph = self.doc.add_paragraph()
        # run=paragraph.add_run()
        style = getattr(para.__class__, '__annotations__')
        # 设置属性值,这种方式便于后期添加属性内容，就不用再繁琐设置了，能偷懒就偷懒
        for attribute, value in vars(style).items():
            # if 'font' not in attribute:
                setattr(paragraph.paragraph_format, attribute, value)
        ## 段落文本
        if para.text is not '' and len(para.fonts)==0:
            para.fonts.append(Font(text=para.text))
        if len(para.fonts)>0:
            for f in para.fonts:
                r=paragraph.add_run(f.text)
                for attribute, value in vars(f).items():
                    if 'color' not in attribute:
                        setattr(r.font, attribute, value)
                    else:
                        ## 颜色有点特殊，需要rgb,字段懒得改
                        r.font.color.rgb = f.color  # 将字体颜色设置为红色（RGB 值）

        ## 图像
        if para.image is not None:
            run = paragraph.add_run()
            run.add_picture(para.image)
            # height = float(run.element.xpath('.//wp:extent')[0].get('cy'))
            # self.height+=height/72

        ## 图表
        if len(para.tables)>0:
            for df in para.tables:
                table = self.doc.add_table(df.shape[0] + 1, df.shape[1])
                # 设置段落的行距为5磅
                paragraph = self.doc.add_paragraph()
                paragraph.paragraph_format.space_after = Pt(1)
                # 设置表格的背景色
                table.style = 'Table Grid'  # 设置带边框的样式
                tc = table._element.xpath('.//w:tcPr')
                for c in tc:
                    c.append(parse_xml(r'<w:shd {} w:fill="#0080FF"/>'.format(nsdecls('w'))))  # 设置背景色为黄色

                # 填充表头
                for i, column_name in enumerate(df.columns):
                    # 设置字体颜色为白色
                    cell_text = table.cell(0, i).paragraphs[0].add_run(column_name)
                    font = cell_text.font
                    font.bold = True  # 设置字体加粗

                arr=[] ##每列最小值的索引
                # 填充数据
                if len(df)>0:
                    for col in range(df.shape[1]):
                        if is_numeric_column(df,df.columns[col]):
                            min=df[df.columns[col]].min()
                            arr.append(df[df[df.columns[col]]==min].index.values+1)
                        else:
                            arr.append([])
                        for row in range(df.shape[0]):
                            table.cell(row + 1, col).text = str(df.iloc[row, col])

                    # 遍历表格的所有单元格
                    for j, col in enumerate(table.columns):
                        for i,cell in enumerate(col.cells):
                            # 设置垂直和水平对齐方式为居中
                            cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                            cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER

                            # 设置单元格中所有段落的字体颜色为白色
                            for paragraph in cell.paragraphs:
                                for run in paragraph.runs:
                                    font = run.font
                                    font.size=Pt(10)
                                    if i in arr[j]:
                                        font.color.rgb = RGBColor(255, 0, 0)  # 设置字体颜色为白色
                                    else:
                                        font.color.rgb = RGBColor(255, 255, 255)  # 设置字体颜色为白色

                # 设置表格水平居中
                table.alignment = WD_TABLE_ALIGNMENT.CENTER

        self.doc.save('temp/test.docx')

def is_numeric_column(df, column):
    """
    判断某列是否是数字列
    :param df:
    :param column:
    :return:
    """
    try:
        pd.to_numeric(df[column])
        return True
    except ValueError:
        return False

# 估算段落高度
def calculate_paragraph_height(paragraph):
    total_height = 0
    for run in paragraph.runs:
        if run.font.size:
            font_size = run.font.size.pt
            line_height = font_size * 1.2  # 行高为字体大小的 1.2 倍
            text_height = len(run.text.split('\n')) * line_height
            total_height += text_height
    return total_height

# 计算表格高度
def calculate_table_height(table):
    total_height = 0
    for row in table.rows:
        for cell in row.cells:
            if cell:
                cell_height = calculate_paragraph_height(cell.paragraphs[0])
                total_height += cell_height
    return total_height

def get_image_height(image_blob):
    with Image.open(image_blob) as img:
        return img.height

